Skip to content

OpenClaw 会话管理与子代理协作

会话(Sessions)和子代理(Sub-agents)是 OpenClaw 实现复杂任务的核心机制。本文详解如何高效管理会话、spawn 子代理、协调多代理协作,构建强大的 AI 工作流。

概述

OpenClaw 的会话系统支持:

  • 主会话 - 与用户的直接交互
  • 子代理会话 - 为特定任务 spawn 的独立 AI 实例
  • ACP 会话 - 与外部 AI 编码工具(如 Codex、Claude Code)集成
  • 会话间通信 - 消息传递、状态共享

通过合理使用会话和子代理,你可以:

  • 🔄 并行处理多个任务
  • 🧠 为不同任务分配合适的模型
  • 📦 隔离复杂任务的上下文
  • ⏱️ 设置独立的超时和重试策略
  • 💾 保持主会话简洁

一、会话系统架构

1.1 会话类型

┌─────────────────────────────────────────────────────┐
│                    会话类型                          │
├─────────────────────────────────────────────────────┤
│  main           │ 主会话,与用户直接交互             │
│  subagent       │ 子代理会话,由主会话 spawn         │
│  acp            │ ACP 会话,与外部编码工具集成       │
│  isolated       │ 隔离会话,独立上下文               │
└─────────────────────────────────────────────────────┘

1.2 会话生命周期

创建 (spawn) → 运行 (running) → 完成 (completed)

              终止 (killed)

1.3 核心 API

API用途说明
sessions_list列出会话获取所有活跃会话
sessions_spawn创建会话spawn 子代理或 ACP 会话
sessions_send发送消息向其他会话发送消息
sessions_history获取历史查看会话消息历史
sessions_yield结束回合等待子代理结果
subagents管理子代理list/kill/steer
session_status查看状态使用量、时间、成本

二、子代理基础

2.1 什么是子代理

子代理是由主会话 spawn 的独立 AI 实例,具有:

  • 独立上下文 - 不共享主会话的历史消息
  • 独立模型 - 可以为不同任务选择不同模型
  • 独立超时 - 设置任务特定的超时时间
  • 独立输出 - 完成后将结果返回给主会话

2.2 何时使用子代理

适合使用子代理的场景:

  • ✅ 长时间运行的任务(>1 分钟)
  • ✅ 需要不同模型专长的任务
  • ✅ 可能失败需要重试的任务
  • ✅ 需要隔离上下文的敏感任务
  • ✅ 可以并行执行的多个任务

不适合使用子代理的场景:

  • ❌ 简单快速的问题(直接处理)
  • ❌ 需要连续对话的任务
  • ❌ 依赖主会话实时上下文的场景

2.3 spawn 子代理

基本用法:

javascript
// 最简单的 spawn
const result = await sessions_spawn({
  task: '分析这个 Python 文件的复杂度',
  attachments: [{
    name: 'main.py',
    content: fileContent,
    encoding: 'utf8'
  }],
  mode: 'run',        // 'run' = 一次性运行,'session' = 持久会话
  runtime: 'subagent' // 'subagent' 或 'acp'
})

console.log(result.output)

完整参数:

javascript
await sessions_spawn({
  // 必需
  task: '任务描述',
  
  // 运行模式
  mode: 'run',           // 'run' | 'session'
  runtime: 'subagent',   // 'subagent' | 'acp'
  
  // 模型配置
  model: 'claude-sonnet-4-5-20250929',  // 可选,使用默认模型
  thinking: 'medium',    // 'low' | 'medium' | 'high'
  
  // 超时配置
  timeoutSeconds: 300,   // 总超时
  runTimeoutSeconds: 180, // 运行超时
  
  // 工作目录
  cwd: '/path/to/workdir',
  
  // 附件
  attachments: [{
    name: 'filename.ext',
    content: 'file content',
    encoding: 'utf8',     // 'utf8' | 'base64'
    mimeType: 'text/plain'
  }],
  
  // 会话配置
  label: 'code-analysis',      // 会话标签
  thread: false,               // 是否线程绑定
  cleanup: 'delete',           // 'delete' | 'keep'
  
  // 沙箱
  sandbox: 'inherit',          // 'inherit' | 'require'
  
  // 输出流
  streamTo: 'parent',          // 流式输出到父会话
  
  // ACP 专用
  agentId: 'codex',            // ACP agent ID
  resumeSessionId: 'uuid'      // 恢复现有 ACP 会话
})

2.4 实战案例 1:代码分析器

javascript
async function analyzeCodebase(repoPath) {
  console.log('🔍 开始代码库分析...')
  
  // 1. 获取文件列表
  const files = await exec({
    command: `find ${repoPath} -name "*.py" -o -name "*.js" -o -name "*.ts" | head -50`
  })
  
  // 2. 为每个文件 spawn 分析子代理
  const analysisPromises = files.stdout.split('\n')
    .filter(f => f.trim())
    .map(async (filePath) => {
      const content = await read({ path: filePath })
      
      return await sessions_spawn({
        task: `分析以下代码文件:
        - 代码质量评分(1-10)
        - 潜在问题列表
        - 优化建议
        - 复杂度评估
        
        返回 JSON 格式结果。`,
        attachments: [{
          name: path.basename(filePath),
          content: content,
          encoding: 'utf8'
        }],
        mode: 'run',
        runtime: 'subagent',
        timeoutSeconds: 120,
        model: 'claude-sonnet-4-5-20250929'  // 代码分析用较强模型
      })
    })
  
  // 3. 并行执行所有分析
  const results = await Promise.all(analysisPromises)
  
  // 4. 汇总结果
  const summary = {
    totalFiles: results.length,
    averageScore: results.reduce((sum, r) => sum + r.score, 0) / results.length,
    issues: results.flatMap(r => r.issues),
    recommendations: results.flatMap(r => r.recommendations)
  }
  
  return summary
}

// 使用
const analysis = await analyzeCodebase('/home/pao/projects/my-app')
console.log(`分析完成:${analysis.totalFiles} 个文件,平均分:${analysis.averageScore}`)

2.5 实战案例 2:多语言翻译工作流

javascript
async function translateDocument(sourcePath, targetLanguages) {
  // 1. 读取源文档
  const sourceContent = await read({ path: sourcePath })
  
  // 2. 为每种语言 spawn 翻译子代理
  const translationPromises = targetLanguages.map(lang => 
    sessions_spawn({
      task: `将以下文档翻译成${lang}。
      
      要求:
      - 保持专业术语准确
      - 保持原文格式(Markdown、代码块等)
      - 本地化示例和文化引用
      - 输出完整翻译,不要省略`,
      
      attachments: [{
        name: 'source.md',
        content: sourceContent,
        encoding: 'utf8'
      }],
      
      mode: 'run',
      runtime: 'subagent',
      timeoutSeconds: 300,
      label: `translate-to-${lang}`
    })
  )
  
  // 3. 等待所有翻译完成
  const translations = await Promise.all(translationPromises)
  
  // 4. 保存翻译结果
  const results = {}
  for (let i = 0; i < targetLanguages.length; i++) {
    const lang = targetLanguages[i]
    const outputPath = sourcePath.replace('.md', `.${lang}.md`)
    
    await write({
      path: outputPath,
      content: translations[i].output
    })
    
    results[lang] = outputPath
  }
  
  return results
}

// 使用
const translated = await translateDocument(
  '/docs/guide.md',
  ['英文', '日文', '法文', '西班牙文']
)
console.log('翻译完成:', translated)

三、会话管理

3.1 列出会话

javascript
// 列出所有会话
async function listAllSessions() {
  return await sessions_list({
    limit: 50,              // 最多返回数量
    activeMinutes: 60,      // 最近 60 分钟活跃
    kinds: ['subagent']     // 过滤类型:'main' | 'subagent' | 'acp'
  })
}

// 查找特定标签的会话
async function findSessionByLabel(label) {
  const sessions = await sessions_list({ limit: 100 })
  return sessions.find(s => s.label === label)
}

// 获取会话状态
async function getSessionStatus(sessionKey) {
  return await session_status({ sessionKey })
}

3.2 会话历史

javascript
// 获取会话历史
async function getSessionHistory(sessionKey, limit = 50) {
  return await sessions_history({
    sessionKey,
    limit,
    includeTools: true  // 包含工具调用记录
  })
}

// 分析会话历史
async function analyzeSession(sessionKey) {
  const history = await getSessionHistory(sessionKey)
  
  const stats = {
    totalMessages: history.messages.length,
    toolCalls: history.messages.filter(m => m.tool).length,
    tokensUsed: history.usage?.total_tokens || 0,
    duration: history.messages[history.messages.length - 1].timestamp - 
              history.messages[0].timestamp
  }
  
  return stats
}

3.3 会话间通信

javascript
// 向其他会话发送消息
async function sendToSession(sessionKey, message) {
  return await sessions_send({
    sessionKey,
    message,
    timeoutSeconds: 60  // 等待响应超时
  })
}

// 向标签匹配的会话发送
async function sendToLabel(label, message) {
  const session = await findSessionByLabel(label)
  if (!session) {
    throw new Error(`未找到标签为 ${label} 的会话`)
  }
  
  return await sessions_send({
    label,  // 直接使用标签
    message
  })
}

// 广播消息到多个会话
async function broadcastToSessions(sessionKeys, message) {
  return await Promise.all(
    sessionKeys.map(key => sendToSession(key, message))
  )
}

3.4 实战案例 3:分布式数据处理

javascript
async function processLargeDataset(inputFile, chunkSize = 1000) {
  // 1. 读取并分块
  const data = await readLargeFile(inputFile)
  const chunks = chunkArray(data, chunkSize)
  
  console.log(`数据分块:${chunks.length} 块,每块 ${chunkSize} 条`)
  
  // 2. 为每个块 spawn 处理子代理
  const chunkPromises = chunks.map(async (chunk, index) => {
    return await sessions_spawn({
      task: `处理以下数据块(第${index + 1}/${chunks.length}块):
      - 数据清洗
      - 格式标准化
      - 异常值检测
      - 生成统计摘要
      
      返回处理后的数据和统计信息。`,
      
      attachments: [{
        name: `chunk-${index}.json`,
        content: JSON.stringify(chunk),
        encoding: 'utf8'
      }],
      
      mode: 'run',
      runtime: 'subagent',
      timeoutSeconds: 180,
      label: `data-processor-${index}`,
      cleanup: 'delete'  // 完成后清理
    })
  })
  
  // 3. 并行处理(限制并发数)
  const CONCURRENCY = 5
  const results = []
  
  for (let i = 0; i < chunkPromises.length; i += CONCURRENCY) {
    const batch = chunkPromises.slice(i, i + CONCURRENCY)
    const batchResults = await Promise.all(batch)
    results.push(...batchResults)
    
    console.log(`进度:${Math.min(i + CONCURRENCY, chunks.length)}/${chunks.length}`)
  }
  
  // 4. 合并结果
  const mergedData = results.flatMap(r => r.processedData)
  const aggregatedStats = aggregateStats(results.map(r => r.stats))
  
  // 5. 保存结果
  await write({
    path: inputFile.replace('.json', '.processed.json'),
    content: JSON.stringify(mergedData, null, 2)
  })
  
  await write({
    path: inputFile.replace('.json', '.stats.json'),
    content: JSON.stringify(aggregatedStats, null, 2)
  })
  
  return {
    totalRecords: mergedData.length,
    stats: aggregatedStats
  }
}

四、子代理管理

4.1 列出子代理

javascript
// 列出所有子代理
async function listSubagents() {
  return await subagents({
    action: 'list',
    recentMinutes: 60  // 最近 60 分钟
  })
}

// 获取子代理详情
async function getSubagentDetails(target) {
  const list = await listSubagents()
  return list.find(a => a.id === target || a.label === target)
}

4.2 终止子代理

javascript
// 终止指定子代理
async function killSubagent(target) {
  return await subagents({
    action: 'kill',
    target
  })
}

// 批量终止
async function killSubagentsByLabel(labelPattern) {
  const agents = await listSubagents()
  const toKill = agents.filter(a => a.label?.includes(labelPattern))
  
  for (const agent of toKill) {
    await killSubagent(agent.id)
    console.log(`已终止:${agent.label}`)
  }
  
  return toKill.length
}

// 终止超时子代理
async function cleanupTimeoutAgents(maxAgeMinutes = 60) {
  const agents = await listSubagents()
  const now = Date.now()
  let cleaned = 0
  
  for (const agent of agents) {
    const age = (now - agent.createdAt) / 1000 / 60
    if (age > maxAgeMinutes && agent.status === 'running') {
      await killSubagent(agent.id)
      cleaned++
    }
  }
  
  return cleaned
}

4.3 调整子代理

javascript
// 向运行中的子代理发送指导
async function steerSubagent(target, message) {
  return await subagents({
    action: 'steer',
    target,
    message
  })
}

// 示例:调整分析方向
async function redirectAnalysis(agentId, newFocus) {
  await steerSubagent(agentId, `
    请调整分析方向,重点关注:${newFocus}
    
    之前分析的内容仍然有效,请在此基础上深入。
  `)
}

4.4 实战案例 4:子代理健康检查

javascript
class SubagentManager {
  constructor() {
    this.maxConcurrent = 10
    this.maxAgeMinutes = 120
  }
  
  // 健康检查
  async healthCheck() {
    const agents = await listSubagents()
    
    const report = {
      total: agents.length,
      running: agents.filter(a => a.status === 'running').length,
      completed: agents.filter(a => a.status === 'completed').length,
      failed: agents.filter(a => a.status === 'failed').length,
      old: 0,
      orphaned: 0
    }
    
    // 检查老旧子代理
    const now = Date.now()
    for (const agent of agents) {
      const age = (now - agent.createdAt) / 1000 / 60
      
      if (age > this.maxAgeMinutes) {
        report.old++
        
        if (agent.status === 'running') {
          console.warn(`⚠️ 子代理运行超时:${agent.label || agent.id}`)
        }
      }
      
      // 检查孤立子代理(父会话已结束)
      if (!agent.parentSession) {
        report.orphaned++
      }
    }
    
    return report
  }
  
  // 自动清理
  async autoCleanup() {
    const cleaned = await cleanupTimeoutAgents(this.maxAgeMinutes)
    console.log(`清理了 ${cleaned} 个超时的子代理`)
    
    // 清理已完成的子代理记录
    const agents = await listSubagents()
    for (const agent of agents) {
      if (agent.status === 'completed' || agent.status === 'failed') {
        // 已完成/失败的子代理可以清理
        // 注意:实际清理可能需要额外 API
      }
    }
  }
  
  // 并发控制
  async spawnWithLimit(task, options) {
    // 检查当前运行数
    const agents = await listSubagents()
    const running = agents.filter(a => a.status === 'running').length
    
    if (running >= this.maxConcurrent) {
      console.log('等待子代理完成...')
      await sleep(5000)
      return this.spawnWithLimit(task, options)
    }
    
    return await sessions_spawn({ task, ...options })
  }
}

// 使用
const manager = new SubagentManager()

// 定期健康检查
setInterval(async () => {
  const report = await manager.healthCheck()
  console.log('子代理状态:', report)
  
  if (report.old > 0 || report.orphaned > 0) {
    await manager.autoCleanup()
  }
}, 5 * 60 * 1000)  // 每 5 分钟

五、ACP 会话集成

5.1 什么是 ACP

ACP(AI Coding Protocol)是 OpenClaw 与外部 AI 编码工具(如 Codex、Claude Code、Gemini CLI)集成的协议。

支持的 ACP Agent:

  • codex - OpenAI Codex CLI
  • claude-code - Anthropic Claude Code
  • gemini - Google Gemini CLI

5.2 spawn ACP 会话

javascript
// 基本用法
async function runCodexTask(task) {
  return await sessions_spawn({
    task,
    runtime: 'acp',
    agentId: 'codex',       // 必需,除非配置了 acp.defaultAgent
    mode: 'run',            // 一次性运行
    timeoutSeconds: 600     // 10 分钟超时
  })
}

// 持久 ACP 会话(用于多轮对话)
async function createPersistentCodexSession(label) {
  return await sessions_spawn({
    task: '初始化编码会话',
    runtime: 'acp',
    agentId: 'codex',
    mode: 'session',        // 持久会话
    thread: true,           // 线程绑定
    label
  })
}

// 恢复现有 ACP 会话
async function resumeCodexSession(sessionId, newTask) {
  return await sessions_spawn({
    task: newTask,
    runtime: 'acp',
    agentId: 'codex',
    resumeSessionId: sessionId,
    mode: 'session'
  })
}

5.3 实战案例 5:自动化代码修复

javascript
async function autoFixCode(repoPath, issueDescription) {
  console.log('🔧 开始自动代码修复...')
  
  // 1. 获取 Git 状态
  const gitStatus = await exec({
    command: `cd ${repoPath} && git status --porcelain`
  })
  
  // 2. spawn ACP 会话进行修复
  const result = await sessions_spawn({
    task: `修复以下代码问题:${issueDescription}
    
    Git 状态:
    ${gitStatus.stdout}
    
    要求:
    1. 分析问题根源
    2. 修改相关代码文件
    3. 运行测试验证修复
    4. 提交更改(如果测试通过)
    
    工作目录:${repoPath}`,
    
    runtime: 'acp',
    agentId: 'codex',
    mode: 'session',
    thread: true,
    label: 'auto-fix',
    timeoutSeconds: 900,    // 15 分钟
    cwd: repoPath
  })
  
  // 3. 验证修复
  const testResult = await exec({
    command: `cd ${repoPath} && npm test`,
    timeout: 120
  })
  
  if (testResult.exitCode === 0) {
    console.log('✅ 修复成功,测试通过')
    
    // 提交更改
    await exec({
      command: `cd ${repoPath} && git add -A && git commit -m "fix: ${issueDescription}"`
    })
  } else {
    console.log('❌ 测试失败,需要人工审查')
    
    // 通知用户
    await sessions_send({
      sessionKey: 'main',
      message: `⚠️ 自动修复完成但测试失败:
      
      问题:${issueDescription}
      测试输出:${testResult.stderr}
      
      请人工审查更改。`
    })
  }
  
  return {
    success: testResult.exitCode === 0,
    output: result.output,
    testResult
  }
}

5.4 ACP 与 Subagent 对比

特性SubagentACP
用途通用 AI 任务编码专用
工具OpenClaw 工具集外部 CLI 工具
工作目录继承或指定通常指定项目目录
持久化支持 session 模式支持 session 模式
适用场景分析、写作、数据处理代码修改、调试、重构

六、高级模式

6.1 工作流编排

javascript
class WorkflowOrchestrator {
  constructor() {
    this.steps = []
    this.context = {}
  }
  
  // 添加步骤
  addStep(name, fn) {
    this.steps.push({ name, fn })
    return this
  }
  
  // 执行工作流
  async execute() {
    const results = {}
    
    for (const step of this.steps) {
      console.log(`执行步骤:${step.name}`)
      
      try {
        const result = await step.fn(this.context)
        results[step.name] = result
        
        // 更新上下文
        Object.assign(this.context, result.context || {})
        
      } catch (error) {
        console.error(`步骤失败:${step.name}`, error)
        
        // 错误处理策略
        if (step.onFailure === 'continue') {
          results[step.name] = { error: error.message }
        } else {
          throw error  // 默认:失败即终止
        }
      }
    }
    
    return { results, context: this.context }
  }
}

// 使用示例:内容发布工作流
const workflow = new WorkflowOrchestrator()
  .addStep('分析需求', async (ctx) => {
    const analysis = await sessions_spawn({
      task: `分析内容需求:${ctx.requirement}`,
      mode: 'run'
    })
    return { analysis: analysis.output }
  })
  .addStep('创建大纲', async (ctx) => {
    const outline = await sessions_spawn({
      task: `基于分析创建大纲:${ctx.analysis}`,
      mode: 'run'
    })
    return { outline: outline.output }
  })
  .addStep('撰写内容', async (ctx) => {
    const content = await sessions_spawn({
      task: `根据大纲撰写内容:${ctx.outline}`,
      mode: 'run',
      timeoutSeconds: 600
    })
    return { content: content.output }
  })
  .addStep('审核质量', async (ctx) => {
    const review = await sessions_spawn({
      task: `审核内容质量:${ctx.content}`,
      mode: 'run'
    })
    return { review: review.output }
  })
  .addStep('发布', async (ctx) => {
    // 发布逻辑
    await publishContent(ctx.content)
    return { published: true }
  })

// 执行
const result = await workflow.execute()

6.2 并行聚合模式

javascript
async function parallelAggregate(tasks, aggregator) {
  // 1. spawn 所有子代理
  const promises = tasks.map(task => 
    sessions_spawn({
      task: task.description,
      mode: 'run',
      label: task.label
    })
  )
  
  // 2. 等待全部完成
  const results = await Promise.allSettled(promises)
  
  // 3. 分离成功和失败
  const successes = results
    .filter(r => r.status === 'fulfilled')
    .map(r => r.value)
  
  const failures = results
    .filter(r => r.status === 'rejected')
    .map(r => r.reason)
  
  // 4. 聚合结果
  const aggregated = await aggregator(successes)
  
  return {
    aggregated,
    successes: successes.length,
    failures: failures.length,
    failureDetails: failures
  }
}

// 使用:多源信息聚合
const report = await parallelAggregate(
  [
    { description: '搜索最新 AI 新闻', label: 'news' },
    { description: '获取技术趋势报告', label: 'trends' },
    { description: '分析社区讨论热点', label: 'community' },
    { description: '整理 GitHub 热门项目', label: 'github' }
  ],
  async (results) => {
    // 使用另一个子代理聚合
    const aggregator = await sessions_spawn({
      task: `聚合以下信息生成综合报告:
      ${results.map((r, i) => `## 来源${i+1}\n${r.output}`).join('\n')}`,
      mode: 'run'
    })
    return aggregator.output
  }
)

6.3 链式处理模式

javascript
async function chainProcess(input, processors) {
  let current = input
  
  for (const processor of processors) {
    console.log(`处理阶段:${processor.name}`)
    
    const result = await sessions_spawn({
      task: processor.task(current),
      mode: 'run',
      timeoutSeconds: processor.timeout || 120
    })
    
    current = result.output
    
    // 可选:质量检查
    if (processor.validate) {
      const valid = await processor.validate(current)
      if (!valid) {
        throw new Error(`阶段 ${processor.name} 输出未通过验证`)
      }
    }
  }
  
  return current
}

// 使用:文章润色链
const polished = await chainProcess(
  draftArticle,
  [
    {
      name: '语法检查',
      task: (text) => `检查并修正以下文本的语法错误:${text}`,
      timeout: 60
    },
    {
      name: '风格优化',
      task: (text) => `优化以下文本的写作风格,使其更专业:${text}`,
      timeout: 90
    },
    {
      name: '结构重组',
      task: (text) => `重组以下文本结构,提升可读性:${text}`,
      timeout: 90
    },
    {
      name: '最终审校',
      task: (text) => `审校以下文本,确保一致性和准确性:${text}`,
      timeout: 60,
      validate: async (text) => {
        // 验证逻辑
        return text.length > 1000
      }
    }
  ]
)

6.4 实战案例 6:智能研究助手

javascript
class ResearchAssistant {
  constructor(topic) {
    this.topic = topic
    this.findings = []
  }
  
  async research() {
    console.log(`📚 开始研究:${this.topic}`)
    
    // 阶段 1:背景调研
    const background = await sessions_spawn({
      task: `调研主题"${this.topic}"的背景信息:
      - 核心概念定义
      - 发展历史
      - 关键人物/组织
      - 当前状态`,
      mode: 'run',
      label: 'background-research'
    })
    this.findings.push({ type: 'background', content: background.output })
    
    // 阶段 2:并行深度研究
    const deepResearch = await Promise.all([
      sessions_spawn({
        task: `分析${this.topic}的技术细节和实现方案`,
        mode: 'run',
        label: 'technical-analysis'
      }),
      sessions_spawn({
        task: `调研${this.topic}的商业应用和案例`,
        mode: 'run',
        label: 'business-analysis'
      }),
      sessions_spawn({
        task: `分析${this.topic}的挑战和未来趋势`,
        mode: 'run',
        label: 'trend-analysis'
      })
    ])
    
    this.findings.push(
      { type: 'technical', content: deepResearch[0].output },
      { type: 'business', content: deepResearch[1].output },
      { type: 'trends', content: deepResearch[2].output }
    )
    
    // 阶段 3:综合报告
    const report = await sessions_spawn({
      task: `基于以下研究发现,撰写综合研究报告:
      
      ${this.findings.map(f => `## ${f.type}\n${f.content}`).join('\n\n')}`,
      mode: 'run',
      timeoutSeconds: 600,
      label: 'report-writing'
    })
    
    return {
      topic: this.topic,
      findings: this.findings,
      report: report.output,
      timestamp: new Date().toISOString()
    }
  }
}

// 使用
const assistant = new ResearchAssistant('AI Agent 自主性')
const result = await assistant.research()

// 保存报告
await write({
  path: `research/${result.topic.replace(/\s+/g, '-')}.md`,
  content: result.report
})

七、最佳实践

7.1 性能优化

并发控制

javascript
// 限制并发子代理数量
const MAX_CONCURRENT = 5
const semaphore = { count: 0, queue: [] }

async function spawnWithSemaphore(task, options) {
  if (semaphore.count >= MAX_CONCURRENT) {
    await new Promise(resolve => semaphore.queue.push(resolve))
  }
  
  semaphore.count++
  
  try {
    return await sessions_spawn({ task, ...options })
  } finally {
    semaphore.count--
    if (semaphore.queue.length > 0) {
      semaphore.queue.shift()()
    }
  }
}

超时设置

javascript
// 根据任务类型设置合理超时
const TIMEOUTS = {
  analysis: 120,      // 分析任务 2 分钟
  writing: 300,       // 写作任务 5 分钟
  coding: 600,        // 编码任务 10 分钟
  research: 900       // 研究任务 15 分钟
}

await sessions_spawn({
  task,
  timeoutSeconds: TIMEOUTS[taskType]
})

7.2 错误处理

javascript
async function spawnWithRetry(task, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await sessions_spawn({ task, ...options })
    } catch (error) {
      if (i === maxRetries - 1) throw error
      
      console.log(`重试 ${i+1}/${maxRetries}: ${error.message}`)
      await sleep(2000 * (i + 1))  // 指数退避
    }
  }
}

7.3 资源管理

javascript
// 定期清理
async function cleanupResources() {
  // 清理超时子代理
  await cleanupTimeoutAgents(120)
  
  // 清理已完成会话
  const sessions = await sessions_list({ limit: 100 })
  for (const session of sessions) {
    if (session.status === 'completed' && session.age > 24 * 60) {
      // 清理超过 24 小时的已完成会话
    }
  }
}

// 监控资源使用
async function monitorUsage() {
  const status = await session_status({})
  
  if (status.usage.total_tokens > 100000) {
    console.warn('⚠️ Token 使用量过高')
  }
  
  if (status.cost > 10) {
    console.warn('⚠️ 成本超过阈值')
  }
}

7.4 调试技巧

javascript
// 详细日志
async function spawnWithLogging(task, options) {
  const startTime = Date.now()
  console.log(`[SPAWN] ${options.label || 'unnamed'}: ${task.slice(0, 50)}...`)
  
  try {
    const result = await sessions_spawn({ task, ...options })
    const duration = Date.now() - startTime
    
    console.log(`[COMPLETE] ${options.label}: ${duration}ms`)
    return result
    
  } catch (error) {
    console.error(`[ERROR] ${options.label}: ${error.message}`)
    throw error
  }
}

// 保存会话快照
async function saveSessionSnapshot(sessionKey) {
  const history = await sessions_history({ sessionKey, includeTools: true })
  
  await write({
    path: `logs/session-${sessionKey}-${Date.now()}.json`,
    content: JSON.stringify(history, null, 2)
  })
}

八、总结

核心要点

  1. 子代理是处理复杂任务的核心工具
  2. 合理设置超时和重试策略
  3. 使用标签组织和管理会话
  4. 定期清理避免资源泄漏
  5. ACP 会话专为编码任务优化

选择指南

场景推荐方案
简单问题直接处理
长时间任务spawn 子代理
编码任务ACP 会话
并行处理多个子代理
多轮对话session 模式
敏感任务隔离会话

进阶方向

  • 📖 研究 OpenClaw 会话源码
  • 🔧 开发自定义会话管理工具
  • 🏗️ 构建复杂工作流编排系统
  • 📊 实现会话分析和优化

🟢🐉 开始构建你的多代理协作系统吧!

Released under the MIT License.